
#include "loirey_VectorMath.h"

// [*] CVectorMath

double CVectorMath::ManhattanDistance(const CSimpleTypeArray<double>& P, const CSimpleTypeArray<double>& Q)
{
	return ManhattanDistance((int)P.Size, P.pElement, Q.pElement);
}

double CVectorMath::ManhattanDistance(int Length, const double* P, const double* Q)
{
	int i;
	double t;
	double ret = 0.0;
	for ( i = 0; i < Length; ++i )
	{
		t = (*P - *Q);
		ret += abs(t);
		++P; ++Q;
	}
	return sqrt(ret);
}

double CVectorMath::EulerDistance(const CSimpleTypeArray<double>& P, const CSimpleTypeArray<double>& Q)
{
	return EulerDistance((int)P.Size, P.pElement, Q.pElement);
}

double CVectorMath::EulerDistance(int Length, const double* P, const double* Q)
{
	int i;
	double t;
	double ret = 0.0;
	for ( i = 0; i < Length; ++i )
	{
		t = (*P - *Q);
		ret += t * t;
		++P; ++Q;
	}
	return sqrt(ret);
}

double CVectorMath::CosineSimilarity(const CSimpleTypeArray<double>& P, const CSimpleTypeArray<double>& Q)
{
	return CosineSimilarity((int)P.Size, P.pElement, Q.pElement);
}

double CVectorMath::CosineSimilarity(int Length, const double* P, const double* Q)
{
	int i;
	double sP = 0.0;
	double sQ = 0.0;
	double ret = 0.0;
	for ( i = 0; i < Length; ++i )
	{
		ret += *P * *Q;
		sP += *P * *P;
		sQ += *Q * *Q;
		++P; ++Q;
	}
	if (sP<MINIMUM_DOUBLE_EPS_C || sQ<MINIMUM_DOUBLE_EPS_C)
		return 0.0;
	else
		return ret/sqrt(sP * sQ);
}

double CVectorMath::KL_Divergence(const CSimpleTypeArray<double>& P, const CSimpleTypeArray<double>& Q)
{
	return KL_Divergence((int)P.Size, P.pElement, Q.pElement);
}

double CVectorMath::KL_Divergence(int Length, const double* P, const double* Q)
{
	int i;
	double ret = 0.0;
	for ( i = 0; i < Length; ++i )
	{
		ret += *P * CMyMath::my_log(*P / *Q);
		++P; ++Q;
	}
	return ret;
}

// [*] loirey::CComplexNumbe

loirey::CComplexNumber loirey::operator + ( const CComplexNumber& A, const CComplexNumber& B )
{
	CComplexNumber r(A); r += B; return r;
}

loirey::CComplexNumber loirey::operator - ( const CComplexNumber& A, const CComplexNumber& B )
{
	CComplexNumber r(A); r -= B; return r;
}

loirey::CComplexNumber loirey::operator * ( const CComplexNumber& A, const CComplexNumber& B )
{
	CComplexNumber r(A); r *= B; return r;
}

loirey::CComplexNumber loirey::operator / ( const CComplexNumber& A, const CComplexNumber& B )
{
	CComplexNumber r(A); r /= B; return r;
}

